package cn.hloger.spider.demo.proxyDemo.annotation;

import cn.hloger.spider.demo.proxyDemo.interceptor.ZhyReqInterceptor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 代理接口处理类
 *
 * @author huanglong
 * @version 1.0
 * @date 2024/2/27
 */
@Component
public class XmProxyHandler {
    @Autowired
    private ZhyReqInterceptor zhyReqInterceptor;

    @Autowired
    private RequestMappingHandlerMapping handlerMapping;

    @Value("${proxy.url.flag:false}")
    private boolean proxyUrlFLag;

    @PostConstruct
    public void init() {
        if (!proxyUrlFLag) {
            return;
        }
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entrySet : handlerMethods.entrySet()) {
            RequestMappingInfo predicateInfo = entrySet.getKey();
            HandlerMethod handlerMethod = entrySet.getValue();
            //先看类上面有没有,再看方法上面有没有
            Class<?> controllerClass = handlerMethod.getMethod().getDeclaringClass();
            boolean hasAnnotation = handleXmProxy(controllerClass.getAnnotation(XmProxyController.class), predicateInfo);
            if (!hasAnnotation) {
                //类上面没有,那么再找方法上有没有
                handleXmProxy(handlerMethod.getMethodAnnotation(XmProxyController.class), predicateInfo);
            }
        }
        Set<String> keySet = zhyReqInterceptor.getProxyPathMap().keySet();
        System.out.println("XmProxyController代理注解扫描执行完成,需要代理的接口个数:" + keySet.size());
        System.out.println(keySet.stream().collect(Collectors.joining(",")));
    }

    private boolean handleXmProxy(XmProxyController annotation, RequestMappingInfo predicateInfo) {
        if (annotation != null && StringUtils.isNotEmpty(annotation.value())) {
            if (predicateInfo.getPathPatternsCondition() != null) {
                predicateInfo.getPathPatternsCondition().getPatterns().forEach(path ->
                        zhyReqInterceptor.putProxyPathMap(path.getPatternString().replace("/" + annotation.value(), ""), path.getPatternString())
                );
            } else if (predicateInfo.getPatternsCondition() != null) {
                predicateInfo.getPatternsCondition().getPatterns().forEach(path ->
                        zhyReqInterceptor.putProxyPathMap(path.replace("/" + annotation.value(), ""), path)
                );
            }
            return true;
        }
        return false;
    }

}
